/*******************************************************************************
 * Copyright (c) 2010 European Software Institute - Tecnalia.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@esi.es)
 *     
 *******************************************************************************/
package es.esi.gemde.vv.modelanalyzer.service.impl;

import java.util.Vector;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;

import es.esi.gemde.vv.modelanalyzer.exceptions.NoSuchOperationException;
import es.esi.gemde.vv.modelanalyzer.exceptions.NoSuchToolException;
import es.esi.gemde.vv.modelanalyzer.exceptions.ToolException;
import es.esi.gemde.vv.modelanalyzer.service.IAnalysisResult;
import es.esi.gemde.vv.modelanalyzer.service.IAnalysisTool;
import es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService;
import es.esi.gemde.vv.modelanalyzer.service.IToolOperation;

/**
 * Implementation of the {@link IModelAnalysisService} interface
 *
 * @author Adri�n Noguero (adrian.noguero@esi.es)
 * @version 1.0
 * @since 1.0
 *
 */
public class ModelAnalysisService implements IModelAnalysisService {
	
	private ToolRegistry registry = new ToolRegistry();
	private static final String TOOL_EXTENSION_ID = "es.esi.gemde.vv.modelanalyzer.tool";
	
	private static final String NAME = "name";
	private static final String OPERATION = "operation";
	private static final String CATEGORY = "category";
	private static final String CLASS = "class";
	
	
	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getToolRepository()
	 */
	@Override
	public IAnalysisTool[] getToolRepository() {
		return registry.getTools();
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getToolRepository()
	 */
	@Override
	public String[] getToolRepositoryNames() {
		return registry.getToolNames();
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getToolsInCategory(java.lang.String)
	 */
	@Override
	public IAnalysisTool[] getToolsInCategory(String category) {
		Vector<IAnalysisTool> res = new Vector<IAnalysisTool>();
		
		for (IAnalysisTool tool : registry.getTools()) {
			if (tool.getCategory().equals(category)) {
				res.add(tool);
			}
		}
		
		return res.toArray(new IAnalysisTool[0]);
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getToolByName(java.lang.String)
	 */
	@Override
	public IAnalysisTool getToolByName(String toolName) {
		return registry.getToolByName(toolName);
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getCategories()
	 */
	@Override
	public String[] getCategories() {
		return registry.getToolCategories();
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getCategoriesWithTool()
	 */
	@Override
	public String[] getCategoriesWithTool() {
		return registry.getToolCategories();
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getToolOperations(java.lang.String)
	 */
	@Override
	public IToolOperation[] getToolOperations(String toolName) throws NoSuchToolException {
		return registry.getToolOperations(toolName);
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#getToolOperationNames(java.lang.String)
	 */
	@Override
	public String[] getToolOperationNames(String toolName) throws NoSuchToolException{
		IToolOperation [] ops = getToolOperations(toolName);
		
		if (ops == null) {
			return null;
		}
		
		String [] result = new String[ops.length];
		for (int i = 0; i < ops.length; i++) {
			result[i] = ops[i].getName();
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.vv.modelanalyzer.service.IModelAnalysisService#runTool(java.lang.String, java.lang.String, org.eclipse.emf.ecore.EObject[])
	 */
	@Override
	public IAnalysisResult runTool(String toolName, String operation, Object[] inputs) throws NoSuchToolException, NoSuchOperationException, ToolException {
		// Check the provided inputs and then delegate to the underlying operation implementation
		IAnalysisTool tool = registry.getToolByName(toolName);
		if (tool == null) {
			throw new NoSuchToolException("The tool '" + toolName + "' is not present in the tool registry");
		}
		return tool.runOperation(operation, inputs);
	}
	
	/**
	 * Method to load the contributing tool extension into GEMDE. 
	 * Not intended to be called by anyone except by the ModelAnalyzerPlugin 
	 * during start-up.
	 */
	public void loadExtensions () {
		// Get the elements contributing in the extension point
		IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TOOL_EXTENSION_ID);
		try {
			for (IConfigurationElement tool : config) {
				String toolName = tool.getAttribute(NAME);
				String toolCat = tool.getAttribute(CATEGORY);
				Vector<IToolOperation> ops = new Vector<IToolOperation>();
				for (IConfigurationElement op : tool.getChildren(OPERATION)) {
					Object opImpl = op.createExecutableExtension(CLASS);
					ops.add((IToolOperation)opImpl);
				}
				IAnalysisTool toolImpl = new AnalysisTool(toolName, toolCat, ops);
				try {
					registry.addTool(toolName, toolImpl);
				}
				catch(IllegalArgumentException iae) {
					iae.printStackTrace();
				}
			}
		}
		catch (CoreException ex) {
			ex.printStackTrace();
		}
	}

}
